
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="css/index.css">

    <script src="js/GPSConvertUtil.js"></script>
    <!-- import Vue before Element -->
    <script src="js/vue.js"></script>
    <!-- import JavaScript -->
    <script src="js/element-ui.js"></script>
    <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
    <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=高德地图accessKey&plugin=AMap.Geocoder"></script>
    <script src="js/axios.min.js"></script>
    <script src="//webapi.amap.com/ui/1.1/main.js?v=1.1.1"></script>
    <title>欢迎使用废弃斑马线报警识别工具</title>
</head>
 
<body>
	<div id='container'></div>
	<div id="app">
		<el-container style="width: 23%">
			<el-header style="width:100%; height: 300px;">
				<h4>欢迎使用废弃斑马线报警识别工具</h4>
                <el-upload
                        class="upload-demo"
                        action="/alarm/upload"
                        :on-change="handleChange"
                        :on-success="handleUploadSuccess"
                        :file-list="fileList">
                    <el-button slot="trigger" size="small" type="primary" >点击上传<i class="el-icon-upload el-icon--right"></i></el-button>
                    <el-button size="small" type="success" @click="handleAnalysis">开始分析<i class="el-icon-data-analysis"></i></el-button>
                    <el-button style="margin-left: 0" size="small" type="warning" @click="handleExport">导出误报边界<i class="el-icon-download"></i></el-button>
                    <div style="margin-top: 20px; font-size: 14px;">
                        误差范围：<el-input-number v-model="errorRange" :min="1" :max="999" size="mini" placeholder="误差范围"></el-input-number> 米
                    </div>
                    <div slot="tip" class="el-upload__tip">请分别上传废弃斑马线报警文件和有效斑马线报警文件</div>
                </el-upload>
			</el-header>
			<el-main>
                <div style="width: 100%;text-align: center;">
                    <span style="font-size: 14px; font-weight: bold;">误报区域列表</span>
                </div>
                <el-table
                        highlight-current-row
                        :data="areaList"
                        max-height="500"
                        :highlight-current-row="true"
                        @current-change="handleAreaChange">
                    <el-table-column
                        prop="address"
                        label="地址">
                    </el-table-column>
                    <el-table-column
                        prop="alarmCount"
                        label="区域内误报数量"
                        width="120">
                    </el-table-column>
                </el-table>
			</el-main>
            <span style="font-size: 14px; font-weight: bold;margin-left: 20px">共{{areaList.length}}条</span>
		</el-container>
	</div>

	<script type="text/javascript">
		// Vue实例化
		var main = new Vue({
			el:'#app',
			data: {
				fileList: [],
                map: '',
                gpsList: [],
                polylines: [],
                errorRange:30,
                areaList: [],
                geocoder : {},
                currentPolyline: {}
			},
			methods: {
			    //选中某行数据
                handleAreaChange(val){
                    var center = val.lnglat;
                    this.map.setZoom(12);
                    //延时执行，使页面跳转中心时更平滑
                    var _this = this;
                    setTimeout(()=>{
                        _this.map.remove(_this.currentPolyline)
                        _this.map.setCenter([center.lng, center.lat]);
                        //高亮显示当前的区域
                        _this.currentPolyline = new AMap.Polygon({
                            path: val.points,
                            fillColor: '#EE3', // 多边形填充颜色
                            borderWeight: 2, // 线条宽度，默认为 1
                            strokeColor: 'red', // 线条颜色
                        });
                        _this.map.add(_this.currentPolyline);
                    }, 1000)
                    setTimeout(()=>{
                        _this.map.setZoom(18);
                    }, 1000)
                },
				// 上传
				handleChange(file, fileList) {
					this.fileList = fileList.slice(-3);
				},
                //上传成功
                handleUploadSuccess(response, file, fileList){
				    var _this = this;
                    if(response.success){
                        data = response.data

                        gaodeGps = []
                        data.forEach(gps=>{
                            var gaodePoint = GPS.gps_gaode(gps.lnglat[0], gps.lnglat[1]);
                            gaodeGps.push({
                                lnglat: [gaodePoint['lng'], gaodePoint['lat']]
                            })
                        })
                        var center = gaodeGps[0];
                        this.map.setCenter(center.lnglat);

                        fillstyle = 'red'
                        if(file.name.indexOf('废弃') < 0){
                            fillstyle = 'green'
                        }
                        AMapUI.load(['ui/misc/PointSimplifier', 'lib/$'], function(PointSimplifier, $) {
                            if (!PointSimplifier.supportCanvas) {
                                alert('当前环境不支持 Canvas！');
                                return;
                            }
                            var pointSimplifierIns = new PointSimplifier({
                                map: _this.map, //所属的地图实例
                                getPosition: function(item) {
                                    if (!item) {
                                        return null;
                                    }
                                    //返回经纬度
                                    return item.lnglat;
                                },
                                getHoverTitle: function(dataItem, idx) {
                                    return dataItem.lnglat;
                                },
                                renderOptions: {
                                    //点的样式
                                    pointStyle: {
                                        width: 6,
                                        height: 6,
                                        fillStyle: fillstyle
                                    },
                                    //鼠标hover时的title信息
                                    hoverTitleStyle: {
                                        position: 'top'
                                    }
                                }
                            });
                            window.pointSimplifierIns = pointSimplifierIns;
                            pointSimplifierIns.setData(gaodeGps);
                        });
                    }
                },
                handleAnalysis(){
                    var _this = this;
                    var param = new URLSearchParams()
                    param.append('errorRange', this.errorRange)
                    axios.post('analysis', param)
                        .then(function(response){
                        if(response.data.success){
                            _this.map.remove(_this.polylines);
                            _this.map.remove(_this.currentPolyline);
                            _this.polylines = [];
                            var lines = response.data.data;
                            _this.areaList = []
                            lines.forEach(line=>{
                                var lineCenter = {};
                                var totalLng = 0.0;
                                var totalLat = 0.0;
                                var path = []
                                line.points.forEach(point=>{
                                    var gaodePoint = GPS.gps_gaode(point.longitude, point.latitude);
                                    var mapPoint = new AMap.LngLat(gaodePoint.lng, gaodePoint.lat)
                                    path.push(mapPoint)
                                    totalLng += point.longitude;
                                    totalLat += point.latitude;
                                })
                                lineCenter = GPS.gps_gaode(totalLng / line.points.length, totalLat / line.points.length);
                                _this.geocoder.getAddress([lineCenter.lng, lineCenter.lat], function(status, result) {
                                    if (status === 'complete'&&result.regeocode) {
                                        var address = result.regeocode.formattedAddress;
                                        _this.areaList.push({
                                            alarmCount : line.alarmCount,
                                            lnglat: {'lng':lineCenter.lng, 'lat':lineCenter.lat},
                                            points: path,
                                            address : address
                                        })
                                    }else{
                                        _this.areaList.push({
                                            alarmCount : line.alarmCount,
                                            address : lineCenter.lng+','+lineCenter.lat,
                                            points: path
                                        })
                                    }
                                })


                                var polyline = new AMap.Polygon({
                                    path: path,
                                    fillColor: '#FBB', // 多边形填充颜色
                                    borderWeight: 2, // 线条宽度，默认为 1
                                    strokeColor: 'red', // 线条颜色
                                });
                                _this.map.add(polyline);
                                _this.polylines.push(polyline);
                            })
                            if(lines.length == 0){
                                Vue.prototype.$message.warning('误差范围过小，请调整后重试')
                            }else{
                                Vue.prototype.$message.success('分析完成')
                            }
                        }else{
                            Vue.prototype.$message.error('请上传废弃斑马线报警文档')
                        }
                    })
                    .catch(function (error) { // 请求失败处理
                        Vue.prototype.$message.error('请求失败，请稍后重试')
                    });
                },
                handleExport(){
                    if(!this.areaList) {
                        alert('导出的数据为空');
                        return;
                    }
                    var filename = '废弃斑马线误报区域.csv'
                    var exportDatas = []
                    this.areaList.forEach((area)=>{
                        var exportData = {}
                        //导出的时候只需要对角两个点，且需要转回84坐标系
                        var leftTopPoint = area.points[0]
                        var leftTopPointGps = GPS.gaode_gps(leftTopPoint.lng, leftTopPoint.lat)
                        var rightBottomPoint = area.points[2]
                        var rightBottomGps =GPS.gaode_gps(rightBottomPoint.lng, rightBottomPoint.lat)
                        var lnglatGps = GPS.gaode_gps(area.lnglat.lng, area.lnglat.lat)
                        exportData.point1 = leftTopPointGps.lng + ','+leftTopPointGps.lat
                        exportData.point2 = rightBottomGps.lng + ','+rightBottomGps.lat
                        exportData.lnglat = lnglatGps.lng + ','+lnglatGps.lat
                        exportData.address = area.address
                        exportData.alarmCount = area.alarmCount
                        exportDatas.push(exportData)
                    })
                    var headers = [
                        {
                            column:"address",
                            title: "address"
                        },{
                            column:"lnglat",
                            title: "lnglat"
                        },{
                            column:"alarmCount",
                            title: "alarmCount"
                        },{
                            column:"point1",
                            title: "point1"
                        },{
                            column:"point2",
                            title: "point2"
                        }
                    ]
                    this.exportCsv(headers, exportDatas, filename)

                    /*var data = JSON.stringify(exportDatas, undefined, 4)
                    var blob = new Blob([data], {type: 'text/json'}),
                        e = document.createEvent('MouseEvents'),
                        a = document.createElement('a')
                    a.download = filename
                    a.href = window.URL.createObjectURL(blob)
                    a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
                    e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
                    a.dispatchEvent(e)*/
                },
                exportCsv(headers, rows, filename) {
                    if (headers.length > 0) { //表头信息不能为空
                        if (!filename || typeof filename != "string") {
                            fileName = "export.csv"
                        }
                        var blob = this.getCsvBlob(headers, rows);
                        if (navigator.msSaveOrOpenBlob) {
                            navigator.msSaveOrOpenBlob(blob, filename);
                        } else {
                            var url = URL.createObjectURL(blob);
                            var downloadLink = document.createElement('a');
                            downloadLink.href = url;
                            downloadLink.download = filename;
                            document.body.appendChild(downloadLink);
                            downloadLink.click();
                            document.body.removeChild(downloadLink);
                            URL.revokeObjectURL(url);
                        }
                    }
                },
                getCsvBlob(headers, rows){
                    var BOM = '\uFEFF';
                    var columnDelimiter = ','; //默认列分隔符','
                    var rowDelimiter = '\r\n'; //默认行分隔符 '\r\n'
                    var csv = headers.reduce((previous, header) => {
                        return (previous ? previous + columnDelimiter : '') + (header.title || header.column);
                    }, '');
                    if (rows.length > 0) {
                        let columns = headers.map(header => header.column);
                        csv = rows.reduce((previous, row) => {
                            var rowCsv = columns.reduce((pre, column) => {
                                if (row.hasOwnProperty(column)) {
                                var cell = row[column];
                                    if (cell != null) {
                                        var header = headers.find(item => item.column == column);
                                        if (header.formatter != null && typeof (header.formatter) == "function") {
                                            cell = header.formatter(cell);
                                        }
                                        if (cell != null) {
                                            cell = cell.toString().replace(new RegExp(rowDelimiter, 'g'), ' '); // 若数据中本来就含行分隔符，则用' '替换
                                            cell = new RegExp(columnDelimiter).test(cell) ? `"${cell}"` : cell; //若数据中本来就含列分隔符，则用""包起来
                                            return pre ? pre + columnDelimiter + cell : pre + cell;
                                        }
                                    }
                                    return pre ? pre + columnDelimiter : pre + " ";//reduce初始值为''，故第一次迭代时不会在行首加列分隔符。后面的遇到值为空或不存在的列要填充含空格的空白" ",则pre返回true，会加列分隔符
                                }else {
                                    return pre ? pre + columnDelimiter : pre + " ";//即使不存在该列也要填充空白，避免数据和表头错位不对应
                                }
                            }, '');
                            return previous + rowDelimiter + rowCsv;
                        }, csv);
                    }
                    var blob = new Blob([BOM + csv], { type: 'text/csv;charset=utf-8;' });
                    return blob;
                },
                initMap(){
				    var _this = this
				    setTimeout(()=>{
                        _this.map = new AMap.Map('container', {zoom: 11});
                        this.geocoder = new AMap.Geocoder();
                    }, 1)

				}
			},
			computed: {
				
			},
			watch: {
			},
			created(){
                this.initMap();
			}
		})
 
	</script>
	<style>
		html,body{
			height: 100%;
			border: 0;
			margin: 0
		}
		
		
		#app {
		  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
		  color: #756C83;
		}
		
		#container {width:75%; height: 95%; margin: 10px 10px; float: right}

	</style>
</body>
 
